package mv.releaser.controler;

import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import mv.releaser.model.MoveAviFileException;
import mv.releaser.model.MvReleaser;
import mv.releaser.view.AboutWindow;
import mv.releaser.view.CommentsWindow;
import mv.releaser.view.CrcWindow;
import mv.releaser.view.MainWindowJFormD;
import mv.releaser.view.PreviewNfoWindow;

public class ControlerMvReleaser {

	private MvReleaser mvReleaser;

	private MainWindowJFormD view;

	private CrcWindow crcPFrame;

	private PreviewNfoWindow nfoPreview;

	private AboutWindow about;

	private CommentsWindow commentsWindow;

	private Thread crcThread;

	private ConfigObject config;

	public ControlerMvReleaser(MvReleaser mvReleaser, ConfigObject config) {
		this.mvReleaser = mvReleaser;
		this.config = config;

		// load skel.nfo
		loadNfo();

		
		
		view = new MainWindowJFormD(this, mvReleaser);
		if (config != null)
			loadConfig();
		view.setLocationRelativeTo(null);
		view.setVisible(true);
	}

	private void loadConfig() {
		new LoadConfiguration(config, mvReleaser, view);
	}

	private void loadNfo() {
		String currentDir = System.getProperties().getProperty("user.dir");

		File fin = new File("skel.nfo");

		if (fin.exists())
			mvReleaser.setNfoTemplate(fin.getAbsolutePath());
		else {
			int answer = JOptionPane
					.showConfirmDialog(
							view,
							"Unable to find nfo.skel in "
									+ currentDir
									+ "\nClick YES to browse to skel.nfo or NO to use default template.",
							"Error", JOptionPane.YES_NO_OPTION);

			if (answer == JOptionPane.YES_OPTION)
				openNfo();
		}
	}

	private void openNfo() {
		JFileChooser fc = new JFileChooser(mvReleaser.getLastOpenPath());
		fc.showOpenDialog(view);
		File fin = fc.getSelectedFile();

		if (fin == null) {
			return;
		}

		mvReleaser.setNfoTemplate(fin.getAbsolutePath());
	}

	public void openAviFile() {
		JFileChooser fc = new JFileChooser(mvReleaser.getLastOpenPath());
		fc.showOpenDialog(view);
		File fin = fc.getSelectedFile();

		if (fin == null) {
			return;
		}

		try {
			mvReleaser.setAviFile(fin);
			mvReleaser.setLastOpenPath(fin.getAbsolutePath());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(view,
					"Error while opening AVI input file.\n" + e.getMessage(),
					"Error", JOptionPane.ERROR_MESSAGE);
		}
	}

	public void crcRefresh() {
		String filePath = mvReleaser.getFilePath();
		if (filePath == null)
			return;

		final File fin = new File(filePath);

		// if file not exists --> exit
		if (!fin.exists())
			return;

		try {
			view.setEnabled(false);
			view.setFocusable(false);

			crcPFrame = new CrcWindow(this, mvReleaser);
			crcPFrame.setResizable(false);
			crcPFrame.setLocationRelativeTo(view);
			crcPFrame.setVisible(true);
			crcPFrame.setAlwaysOnTop(true);

			crcThread = new Thread() {
				public void run() {
					try {
						long crcCode = crcPFrame.getCRC(fin);
						mvReleaser.setCrc(Long.toHexString(crcCode));
						mvReleaser.notifyObservers();
						crcPFrame.dispose();
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						view.setEnabled(true);
						view.setFocusable(true);
						view.setVisible(true);
					}
				}
			};
			crcThread.start();

		} catch (Exception e) {
			JOptionPane.showMessageDialog(view,
					"Error while calculating checksum for : " + filePath,
					"Error", JOptionPane.ERROR_MESSAGE);
		}
	}

	public void crcProgressBarClosing() {
		if (crcThread.isAlive())
			return;

		// should never reach that
		crcPFrame.dispose();
		view.setEnabled(true);
		view.setFocusable(true);
		view.setVisible(true);
	}

	public void generate() {
		if (mvReleaser.getFilePath() == null
				|| mvReleaser.getFilePath().equals("")) {
			JOptionPane.showMessageDialog(view, "Please select a file.",
					"Error", JOptionPane.ERROR_MESSAGE);
			return;
		}

		updateMvReleaser();
		if (mvReleaser.getReleaseName().equals("")) {
			JOptionPane.showMessageDialog(view,
					"Please fill release informations", "Error",
					JOptionPane.ERROR_MESSAGE);
			return;
		}

		JFileChooser fc = new JFileChooser(mvReleaser.getLastSavePath());
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fc.setDialogTitle("Please select output directory");
		fc.showSaveDialog(view);
		final File dout = fc.getSelectedFile();

		// cancel clicked ?
		if (dout == null)
			return;

		if (view.getCrc() == null || view.getCrc().equals("")) {
			Thread thread = new Thread() {
				public void run() {
					crcRefresh();
					makeRelease(dout);
				}
			};
			thread.start();
		} else
			makeRelease(dout);

	}

	private void makeRelease(File dout) {
		try {
			mvReleaser.setLastSavePath(dout.getAbsolutePath());
			mvReleaser.makeRelease(dout);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(view,
					"Error while making the release :\n" + e.getMessage(),
					"Error", JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		} catch (MoveAviFileException e) {
			int answer = JOptionPane.showConfirmDialog(view,
					"Unable to move : " + mvReleaser.getAviFilename()
							+ "\nDo you want to copy it ?", "Error",
					JOptionPane.ERROR_MESSAGE);
			if (answer == JOptionPane.YES_OPTION) {
				boolean success = mvReleaser.copyAviFile();
				if (!success) {
					JOptionPane.showMessageDialog(view,
							"Unable to copy AVI file.", "Error",
							JOptionPane.ERROR_MESSAGE);
				}
			}
		}
	}

	private void updateMvReleaser() {

		// release informations
		mvReleaser.setArtist(view.getArtist());
		mvReleaser.setTitle(view.getTitleSong());
		mvReleaser.setRipper(view.getRipper());
		mvReleaser.setGroup(view.getGroup());
		mvReleaser.setReleaseName(view.getRelease());

		// release details
		mvReleaser.setGenre(view.getGenre());
		mvReleaser.setType(view.getType());
		mvReleaser.setAudio(view.getAudio());
		mvReleaser.setSource(view.getSource());
		mvReleaser.setLang(view.getLanguage());
		mvReleaser.setDeinterlace(view.getDeinterlace());
		mvReleaser.setCrc(view.getCrc());
		mvReleaser.setReleaseDate(view.getDate());
		mvReleaser.setYear(view.getYear());

		// video details
		mvReleaser.setFormat(view.getFormat());
		mvReleaser.setFps(view.getFps());
		try {
			mvReleaser.setMinutes(Integer.parseInt(view.getMinutes()));
			mvReleaser.setSeconds(Integer.parseInt(view.getSeconds()));
			mvReleaser.setWidth(Integer.parseInt(view.getWidthResolution()));
			mvReleaser.setHeight(Integer.parseInt(view.getHeightResolution()));
		} catch (NumberFormatException e) {
			e.getMessage();
			e.printStackTrace();
		}
		
		// options
		mvReleaser.setHdtv(view.isHdtv());
		mvReleaser.setDvdrip(view.isDvdrip());
		mvReleaser.setProper(view.isProper());
		mvReleaser.setRepack(view.isRepack());
		mvReleaser.setReadnfo(view.isReadNfo());
		mvReleaser.setDirfix(view.isDirFix());
		mvReleaser.setNfoFix(view.isNfoFix());
	}

	public void previewNFO() {
		try {
			updateMvReleaser();
			String s = mvReleaser.previewNFO();

			view.setEnabled(false);
			view.setFocusable(false);

			nfoPreview = new PreviewNfoWindow(this);
			nfoPreview.setLocationRelativeTo(view);
			nfoPreview.setNfoText(s);
			nfoPreview.setVisible(true);
			nfoPreview.setAlwaysOnTop(true);

		} catch (Exception e) {
			e.getMessage();
			e.printStackTrace();
		}
	}

	public void previewNfoWindowClosing() {
		nfoPreview.dispose();
		view.setEnabled(true);
		view.setFocusable(true);
		view.setVisible(true);
	}

	public void openAviFile(File fin) {
		try {
			mvReleaser.setAviFile(fin);
			mvReleaser.setLastOpenPath(fin.getAbsolutePath());

		} catch (Exception e) {
			JOptionPane.showMessageDialog(view,
					"Error while opening AVI input file.\n" + e.getMessage(),
					"Error", JOptionPane.ERROR_MESSAGE);
		}

	}

	public void about() {
		view.setEnabled(false);
		view.setFocusable(false);

		about = new AboutWindow(this);
		about.setLocationRelativeTo(view);
		about.setVisible(true);
		about.setAlwaysOnTop(true);

	}

	public void aboutClosing() {
		about.dispose();
		view.setEnabled(true);
		view.setFocusable(true);
		view.setVisible(true);
	}

	public void commentsClosing() {
		String s = commentsWindow.getComments();
		mvReleaser.setComments(s);

		commentsWindow.dispose();
		view.setEnabled(true);
		view.setFocusable(true);
		view.setVisible(true);
	}

	public void comments() {
		view.setEnabled(false);
		view.setFocusable(false);

		commentsWindow = new CommentsWindow(this, mvReleaser);
		commentsWindow.setLocationRelativeTo(view);
		commentsWindow.setVisible(true);
		commentsWindow.setAlwaysOnTop(true);
	}

	public void saveConfiguration() {
		new SaveConfiguration(config, mvReleaser, view);
		view.dispose();
		System.exit(0);
	}
}
